﻿using Company.Application.Share.Entities;
using Company.Application.Share.Extensions;
using Company.Application.Share.Interfaces;
using Company.Core;
using Company.Core.Helpers;
using Company.Core.Models;
using Company.Hardware.Base;
using Company.Hardware.Base.Extensions;
using Prism.Modularity;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Company.Application.Station.Services
{
    class StationManager : BindableBase, IStationManager
    {
        private bool isStarted = false;
        public ObservableCollection<StationEntity> Stations { get; set; } = new();

        private StationEntity? station;
        public StationEntity? Station
        {
            get => station;
            set=>SetProperty(ref station, value);
        }

        private IWebManager WebManager { get; }
        private ISession Session { get; }
        private IModuleManager ModuleManager { get; }
        private IUploader Uploader { get; }

        public ObservableCollection<string> Messages { get; set; } = new();

        public StationManager(
            IUploader uploader,
            IModuleManager moduleManager,
            ISession session,
            IWebManager webManager)
        {
            Uploader = uploader;
            ModuleManager = moduleManager;
            WebManager = webManager;
            Session = session;
        }

        /// <summary>
        /// 获取当前医院所有站点
        /// </summary>
        /// <returns></returns>
        private async Task<List<StationEntity>> GetStationsAsync()
        {
            var result = await WebManager.GetStationsAsync<Result<List<StationEntity>>>(Session.CurrentHospital.Id);
            if (result != null && result.Success && result.Value != null)
            {
                return result.Value;
            }
            return new List<StationEntity>();
        }
        /// <summary>
        /// 获取当前站点所有设备
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        private async Task<List<DeviceEntity>> GetDevicesAsync(StationEntity station)
        {
            var result = await WebManager.GetDevicesAsync<Result<List<DeviceEntity>>>(station.HospitalId, station.Id);
            if (result != null && result.Success && result.Value != null)
            {
                return result.Value;
            }
            return new List<DeviceEntity>();
        }


        /// <summary>
        /// 开始所有站点的运行
        /// </summary>
        /// <returns></returns>
        public async Task StartAsync()
        {
            if(isStarted)
            {
                return;
            }
            var stations = await GetStationsAsync();
            var tasks = new List<Task>();
            foreach (var station in stations)
            {
                if (station.Status == (int)StatusType.停用)
                {
                    Messages.Add($"站点[{station.Name}]已停用");
                    continue;
                }

                //获取当前站点所有设备
                var devices = await GetDevicesAsync(station);
                foreach (var device in devices)
                {
                    if (device.Status == (int)StatusType.停用)
                    {
                        Messages.Add($"设备[{device.Name}]已停用");
                        continue;
                    }

                    /* 设备包含了连接信息，包含一定的功能
                     * 只有属性成员的设备：DDD模式当中称为贫血模型
                     * 如果还有方法成员或其他成员：具备功能的模型称为充血模型
                     * 
                     */

                    device.Add(ModuleManager);//给设备添加模块管理器
                    device.Add(Uploader);//给设备添加上传数据服务类
                    var type = ModuleManager.Get().FirstOrDefault(t => t.FullName == device.ClassName);//获取设备的解码器
                    if (type != null)
                    {
                        var decoder = Activator.CreateInstance(type) as IDecoder;//实例化解码器
                        if(decoder != null)
                        {
                            device.Add(decoder);
                            decoder.OnNotify += Decoder_OnNotify;
                        }
                        else
                        {
                            Logs.Error($"没有找到{device.Name}-{device.ClassName}的实例");
                            Decoder_OnNotify($"没有找到{device.Name}-{device.ClassName}的实例");
                        }
                    }
                    else
                    {
                        Logs.Error($"没有找到{device.Name}-{device.ClassName}的反射");
                        Decoder_OnNotify($"没有找到{device.Name}-{device.ClassName}的反射");
                    }
                    var t = device.Run();//让设备运行起来
                    tasks.Add(t);
                    station.Add(device);
                }
                Stations.Add(station);
            }
            await Task.WhenAll(tasks);
            isStarted = true;
        }

        private void Decoder_OnNotify(string message)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(() => Messages.Add(message));
        }
    }
}
